/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xos_http.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../data_struct/head.h"
#include "../config/head.h"
#include "../macro/head.h"
#include "../impl/head.h"
#include "../msg/head.h"
#include "xos_load.h"

namespace xos_http
{

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    xos_load::xos_load()
    {
    }

    xos_load::~xos_load()
    {
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int xos_load::load()
    {
        int ret = 0;

        xos_box::i_string * pString = mgr::container()->box()->string();
        xos_box::i_str_property * pProp = 0;
        std::string module_root_path;

        {
            mgr::container()->misc()->get_process_path( pString );
            mgr::container()->misc()->path_append( pString, config::get()->m_web_root.c_str() );
            module_root_path = pString->get( 0, 0 );
        }

        {
            xos::i_dir * pDir = mgr::container()->xos()->dir();
            pDir->scan_dir_and_files( xos::i_dir::FILE_TYPE_BOTH, "xos", module_root_path.c_str(), &pProp, -1 );
            xos_stl::release_interface( pDir );
        }

        {
            port_scan( module_root_path.c_str(), port::get(), pProp );
        }

        xos_stl::release_interface( pString );
        xos_stl::release_interface( pProp );

        return ret;
    }

    int xos_load::port_scan( const char * lpszPath, xos_box::i_str_property * pIn, xos_box::i_str_property * pOut )
    {
        int ret = 0;

        xos_box::i_string * pString = mgr::container()->box()->string();

        int nNum = 0;
        {
            nNum = pOut->size();
            pOut->reset();
        }
        for( int i = 0; i < nNum; ++i )
        {
            xos_box::i_variant * pV = 0;
            const char * pName = 0;
            port * pPort = 0;
            {
                pV = pOut->next( &pName, 0, 0, 0 );
            }
            if( xos_box::i_variant::VT_STR_PROPERTY != pV->get_type( 0 ) )
            {
                continue;
            }
            {
                pPort = port::get_item_from_pool();
                pPort->init();
            }
            {
                pString->set( lpszPath );
                mgr::container()->misc()->path_append( pString, pName );
                pPort->m_full_path = pString->get( 0, 0 );
            }
            {
                pString->set( pPort->m_full_uri.c_str() );
                pString->url_append( pName );
                pPort->m_full_uri = pString->get( 0, 0 );
            }
            {
                pPort->m_nPort = mgr::container()->crt()->atoi( pName );
                pPort->m_port = pName;
                LOG4( "port : full path = %s", pPort->m_full_path.c_str() );
                LOG4( "port : full uri = %s", pPort->m_full_uri.c_str() );
                LOG4( "port : port = %s", pPort->m_port.c_str() );
            }
            pIn->set_obj( pName, pPort, true );
            // scan host
            {
                xos_box::i_str_property * pOutProp = pV->str_prop( 0 );
                xos_box::i_str_property * pInProp = pPort->m_pProp;
                host_scan( pPort, pInProp, pOutProp );
                pPort->load_cert();
            }
        }

        xos_stl::release_interface( pString );

        return ret;
    }

    int xos_load::host_scan( port * pPort, xos_box::i_str_property * pIn, xos_box::i_str_property * pOut )
    {
        int ret = 0;

        xos_box::i_string * pString = mgr::container()->box()->string();
        int nNum = 0;
        {
            nNum = pOut->size();
            pOut->reset();
        }
        for( int i = 0; i < nNum; ++i )
        {
            xos_box::i_variant * pV = 0;
            const char * pName = 0;
            {
                pV = pOut->next( &pName, 0, 0, 0 );
            }
            if( xos_box::i_variant::VT_STR_PROPERTY != pV->get_type( 0 ) )
            {
                continue;
            }
            host * pHost = 0;
            {
                pHost = host::get_item_from_pool();
                pHost->init();
                pHost->m_pPort = pPort;
            }
            {
                pString->set( pPort->m_full_path.c_str() );
                pString->url_append( pName );
                pHost->m_full_path = pString->get( 0, 0 );
            }
            {
                pString->set( pPort->m_full_uri.c_str() );
                pString->url_append( pName );
                pHost->m_full_uri = pString->get( 0, 0 );
            }
            {
                pHost->m_host = pName;
                LOG4( "host : full path = %s", pHost->m_full_path.c_str() );
                LOG4( "host : full uri = %s", pHost->m_full_uri.c_str() );
                LOG4( "host : host = %s", pHost->m_host.c_str() );
                pIn->set_obj( pName, pHost, true );
            }
            // scan path
            path * pPath = 0;
            {
                pPath = path::get_item_from_pool();
                pPath->init();
            }
            {
                pPath->m_full_path = pHost->m_full_path;
                pPath->m_full_uri = pHost->m_full_uri;
                pPath->m_path = pName;
            }
            {
                xos_box::i_str_property * pOutProp = pV->str_prop( 0 );
                xos_box::i_str_property * pInProp = pHost->m_pProp;
                path_scan( pPath, pInProp, pOutProp, 0 );
                pHost->load_cert();
            }
            xos_stl::release_interface( pPath );
        }

        xos_stl::release_interface( pString );

        return ret;
    }

    int xos_load::path_scan( path * pRootPath, xos_box::i_str_property * pIn, xos_box::i_str_property * pOut, int nDepth )
    {
        int ret = 0;

        xos_box::i_string * pString = mgr::container()->box()->string();
        int nNum = 0;
        {
            nNum = pOut->size();
            pOut->reset();
        }
        for( int i = 0; i < nNum; ++i )
        {
            std::string full_path, full_uri;
            xos_box::i_variant * pV = 0;
            const char * pName = 0;
            {
                pV = pOut->next( &pName, 0, 0, 0 );
            }
            {
                pString->set( pRootPath->m_full_path.c_str() );
                pString->url_append( pName );
                full_path = pString->get( 0, 0 );
            }
            {
                pString->set( pRootPath->m_full_uri.c_str() );
                pString->url_append( pName );
                full_uri = pString->get( 0, 0 );
            }
            if( xos_box::i_variant::VT_STR_PROPERTY == pV->get_type( 0 ) )
            {
                xos_box::i_str_property * pOutProp = 0;
                path * pPath = 0;
                {
                    pOutProp = pV->str_prop( 0 );
                    pPath = path::get_item_from_pool();
                    pPath->init();
                }
                {
                    if( nDepth > 0 )
                    {
                        pPath->m_pFatherPath = pRootPath;
                    }
                    pPath->m_full_path = full_path;
                    pPath->m_full_uri = full_uri;
                    pPath->m_path = pName;
                    /*
                    LOG4( "path : full path = %s", pPath->m_full_path.c_str() );
                    LOG4( "path : full uri = %s", pPath->m_full_uri.c_str() );
                    LOG4( "path : path = %s", pPath->m_path.c_str() );
                    */
                    pIn->set_obj( pName, pPath, true );
                }
                path_scan( pPath, pPath->get_dir_prop(), pOutProp, nDepth + 1);
            }
            else if( nDepth > 0 )
            {
                xos::i_file * pXosFile = 0;
                module::T * pModule = 0;
                {
                    pXosFile = (xos::i_file *)pV->obj( 0 );
                    xos_stl::init_pool_item( pModule );
                }
                {
                    pXosFile->get_file_time( 0, 0, &pModule->m_mTime );
                    pModule->m_full_path = pRootPath->m_full_path;
                    pModule->m_full_file = full_path;
                    pModule->m_full_uri = full_uri;
                    pModule->m_file = pName;
                }
                // 只收集xos文件
                if( 0 == pModule->proc_file() )
                {
                    {
                        pModule->m_uri_path = pModule->m_pServletMgr->path();
                        pModule->m_full_uri = pModule->m_pServletMgr->uri();
                        pModule->m_id = pModule->m_pServletMgr->id();
                        pString->set( pRootPath->m_full_uri.c_str() );
                        pString->url_append( pModule->m_id.c_str() );
                        full_uri = pString->get( 0, 0 );
                    }
                    LOG4( "file : full file = %s", pModule->m_full_file.c_str() );
                    LOG4( "file : full path = %s", pModule->m_full_path.c_str() );
                    LOG4( "file : xos uri = %s", pModule->m_full_uri.c_str() );
                    LOG4( "file : cal uri = %s", full_uri.c_str() );
                    LOG4( "file : file = %s", pModule->m_file.c_str() );
                    LOG4( "file : name = %s", pModule->m_name.c_str() );
                    LOG4( "file : ext = %s", pModule->m_ext.c_str() );
                    LOG4( "file : id = %s", pModule->m_id.c_str() );
                    {
                        pModule->m_full_uri = full_uri;
                        file * pFile = 0;
                        file * pF = mgr::get()->get_file_or_add_or_create_if_not_find( pModule->m_full_uri.c_str(), &pFile, false );
                        if( pF == pFile )
                        {
                            pFile->m_pFatherPath = pRootPath;
                            pFile->set_module( pModule );
                            pRootPath->add_file( pModule->m_id.c_str(), pFile );
                            pFile = 0;
                        }
                        else
                        {
                            LOG4( "add file failed : %s exist", pModule->m_id.c_str() );
                        }
                    }
                }
                xos_stl::release_ref( pModule );
            }
        }
        pRootPath->sort_file();
        xos_stl::release_interface( pString );

        return ret;
    }

} // xos_http
